package il.ac.bgu.cs.heuristics.ui;

import il.ac.bgu.cs.heuristics.integration.ISearchAlgorithm;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Collections;
import java.util.Set;

import javaff.data.Action;
import javaff.data.GroundProblem;
import javaff.data.Plan;
import javaff.data.TimeStampedPlan;
import javaff.data.TotalOrderPlan;
import javaff.data.UngroundProblem;
import javaff.parser.PDDL21parser;
import javaff.planning.FFState;
import javaff.planning.TemporalMetricState;
import javaff.scheduling.JavaFFScheduler;

import org.apache.log4j.Logger;

/**
 * 
 * @author Ronen Pinko
 * 
 */
final public class UiUtils {
	private final static Logger	LOG			= Logger.getLogger(UiUtils.class);

	private static final Plan	EMPTY_PLAN	= new Plan() {

												private final static String	NO_PLAN_OUTPUT	= "no plan was found";

												@Override
												public void print(PrintWriter p) {
													p.println(NO_PLAN_OUTPUT);
												}

												@Override
												public void print(PrintStream p) {
													p.println(NO_PLAN_OUTPUT);
												}

												@Override
												public Set<Action> getActions() {
													return Collections
															.emptySet();
												}

												@Override
												public void print(Writer writer) {
													try {
														writer
																.append(NO_PLAN_OUTPUT);
													} catch (IOException e) {
														LOG
																.error(
																		"should never happen",
																		e);
													}
												}
											};

	private UiUtils() {
	}

	public static String planToString(File domain, File problem,
			ISearchAlgorithm<FFState> searchAlgorithm) {
		// ********************************
		// Parse and Ground the Problem
		// ********************************

		final UngroundProblem unground = PDDL21parser.parseFiles(domain,
				problem);

		if (unground == null) {
			throw new IllegalArgumentException(
					"Parsing error - see console for details");
		}

		final GroundProblem ground = unground.ground();

		// ********************************
		// Search for a plan
		// ********************************

		// Get the initial state
		final TemporalMetricState initialState = ground
				.getTemporalMetricInitialState();
		final FFState goalState = searchAlgorithm.search(initialState);
		TimeStampedPlan tsp = null;
		if (goalState != null) {
			tsp = new JavaFFScheduler(ground)
					.schedule((TotalOrderPlan) goalState.getSolution());

		}

		final Writer writer = new StringWriter();
		if (tsp == null) {
			EMPTY_PLAN.print(writer);
		} else {
			tsp.print(writer);
		}

		return writer.toString();
	}

	static void showErrorDialog(String errorMessage) {
		final ErrorDialog error = new ErrorDialog(errorMessage);
		error.setVisible(true);
	}

}
